<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>固定高度</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      ul,
      ol {
        list-style: none;
      }

      html,
      body {
        height: 100%;
      }

      body {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        gap: 20px;
      }

      .container {
        height: 500px;
        border: 1px solid;
        overflow-y: scroll;
      }

      .list {
        width: 500px;
        box-sizing: border-box;
      }

      .item {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 57px;
        border-bottom: 1px solid gray;
        box-sizing: border-box;
      }
    </style>
  </head>
  <body>
    <button class="btn">渲染数据</button>
    <div class="container">
      <ul class="list">
        <li class="item">1</li>
      </ul>
    </div>
    <script>
      // 核心思路：
      // 1. ul高度设置总高度，让滚动条准确
      // 2. 移除多少个item，就用 padding-top来占位
      // 3. onScroll 不需要加节流，不然造成渲染不及时
      const $btn = document.querySelector(".btn");
      const $list = document.querySelector(".list");
      const $container = document.querySelector(".container");
      const datas = new Array(100000)
        .fill(0)
        .map((v, i) => `${i}#${Math.random().toString(36).slice(2)}`);

      const fixHeight = 57;
      let startIndex = 0;
      const pageNum = 20;

      // function render() {
      //   $list.innerHTML = datas
      //     .map((d, i) => `<li class="item">${i}</li>`)
      //     .join("");
      // }

      function render() {
        const top = startIndex * fixHeight; // 移除多少个item，就用 padding-top来占位
        $list.style.paddingTop = `${top}px`;
        $list.innerHTML = datas
          .slice(startIndex, startIndex + pageNum)
          .map((d) => `<li class="item">${d}</li>`)
          .join("");
      }

      $btn.addEventListener("click", function (e) {
        $list.style.height = `${fixHeight * datas.length}px`;
        render();
      });

      $container.addEventListener("scroll", function (e) {
        const scrollTop = this.scrollTop; // 已滚动高度
        // const count = Math.floor(scrollTop / fixHeight); // 滚动了多个item，向下取整，count 刚好就是可渲染的 startIndex
        startIndex = Math.floor(scrollTop / fixHeight);
        console.log(startIndex, scrollTop);
        render();
      });
    </script>
  </body>
</html>
